/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor./
 */
package encryption;
import java.awt.Image;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.imageio.ImageIO;
/**
 *
 * @author kgills
 */

public class EncryptionWindowMain extends javax.swing.JFrame {
    
    public enum ETypes {
        AES,
        DES,
        DESEDE
    }
    
    public enum Action {
    ENCRYPT,
    DECRYPT,
    XOR
    }
    
    Action prevAction;
    
    
    
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];

        for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                 + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
    
    final protected static char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        int v;
        for ( int j = 0; j < bytes.length; j++ ) {
            v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
    
    public static byte[] xorByteArray(byte[] a, byte[] b){
        int i = 0;
        if(a.length > b.length)
            i = a.length;
        else
            i = b.length;
        byte[] out = new byte[i];
        for (int j = 0; j < a.length; j++) {
            out[j] = (byte) (a[j] ^ b[j]);
        }
        return out;
    }
    
    

    /**
     * Creates new form EncryptionWindowMain
     */
    public EncryptionWindowMain() {
        try{
        Image i = ImageIO.read(getClass().getResource("/black.png"));
        setIconImage(i);
        }catch(Exception e){
            e.printStackTrace();
        }
        
        initComponents();
        jPanel1.transferFocusBackward();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        Open_fileChooser = new javax.swing.JFileChooser();
        Save_fileChooser = new javax.swing.JFileChooser();
        Encrypt_button = new javax.swing.JButton();
        Decrypt_button = new javax.swing.JButton();
        key = new javax.swing.JTextField();
        base = new javax.swing.JTextField();
        result = new javax.swing.JTextField();
        XOR_button = new javax.swing.JButton();
        Base_label = new javax.swing.JLabel();
        Key_label = new javax.swing.JLabel();
        Result_label = new javax.swing.JLabel();
        Cipher_label = new javax.swing.JLabel();
        Cipher_text = new javax.swing.JLabel();
        Base_file = new javax.swing.JButton();
        Key_file = new javax.swing.JButton();
        IV = new javax.swing.JTextField();
        IV_text = new javax.swing.JLabel();
        IV_file = new javax.swing.JButton();
        zero_base = new javax.swing.JButton();
        key_base = new javax.swing.JButton();
        zero_key = new javax.swing.JButton();
        key_key = new javax.swing.JButton();
        zero_IV = new javax.swing.JButton();
        key_IV = new javax.swing.JButton();
        spacing_text = new javax.swing.JLabel();
        spacing = new javax.swing.JComboBox();
        jPanel1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        Menu_bar = new javax.swing.JMenuBar();
        Save_button = new javax.swing.JMenu();
        open_button = new javax.swing.JMenuItem();
        save_button = new javax.swing.JMenuItem();
        Quit_button = new javax.swing.JMenuItem();
        Cipher_menu = new javax.swing.JMenu();
        DES_Menu = new javax.swing.JMenuItem();
        DES3_menu = new javax.swing.JMenuItem();
        AES_menu = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Encryption Tool");
        setBackground(new java.awt.Color(255, 255, 255));

        Encrypt_button.setText("Encrypt");
        Encrypt_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Encrypt_buttonActionPerformed(evt);
            }
        });

        Decrypt_button.setText("Decrypt");
        Decrypt_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Decrypt_buttonActionPerformed(evt);
            }
        });

        base.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                baseActionPerformed(evt);
            }
        });

        result.addContainerListener(new java.awt.event.ContainerAdapter() {
            public void componentAdded(java.awt.event.ContainerEvent evt) {
                resultComponentAdded(evt);
            }
        });
        result.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                resultActionPerformed(evt);
            }
        });
        result.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                resultPropertyChange(evt);
            }
        });

        XOR_button.setText("XOR");
        XOR_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                XOR_buttonActionPerformed(evt);
            }
        });

        Base_label.setText("Base (hex)");

        Key_label.setText("Key (hex)");

        Result_label.setText("Result (hex)");

        Cipher_label.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        Cipher_label.setText("Cipher:");

        Cipher_text.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        Cipher_text.setForeground(new java.awt.Color(255, 51, 51));
        Cipher_text.setText("DES");

        Base_file.setText("File");
        Base_file.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Base_fileActionPerformed(evt);
            }
        });

        Key_file.setText("File");
        Key_file.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Key_fileActionPerformed(evt);
            }
        });

        IV.setText("0000000000000000");

        IV_text.setText("IV (hex)");

        IV_file.setText("File");
        IV_file.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                IV_fileActionPerformed(evt);
            }
        });

        zero_base.setText("8B Zero");
        zero_base.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                zero_baseActionPerformed(evt);
            }
        });

        key_base.setText("8B Key");
        key_base.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                key_baseActionPerformed(evt);
            }
        });

        zero_key.setText("8B Zero");
        zero_key.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                zero_keyActionPerformed(evt);
            }
        });

        key_key.setText("8B Key");
        key_key.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                key_keyActionPerformed(evt);
            }
        });

        zero_IV.setText("8B Zero");
        zero_IV.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                zero_IVActionPerformed(evt);
            }
        });

        key_IV.setText("8B Key");
        key_IV.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                key_IVActionPerformed(evt);
            }
        });

        spacing_text.setText("Spacing");

        spacing.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "0", "1", "2", "4", "8", "16", "32"}));
        spacing.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                spacingActionPerformed(evt);
            }
        });

        jPanel1.setBackground(new java.awt.Color(255, 255, 255));
        jPanel1.setOpaque(false);

        jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/new_logo.png"))); // NOI18N
        jLabel1.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 342, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(0, 0, Short.MAX_VALUE)
                    .addComponent(jLabel1)
                    .addGap(0, 0, Short.MAX_VALUE)))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 256, Short.MAX_VALUE)
            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(jPanel1Layout.createSequentialGroup()
                    .addGap(0, 0, Short.MAX_VALUE)
                    .addComponent(jLabel1)
                    .addGap(0, 0, Short.MAX_VALUE)))
        );

        Save_button.setText("File");

        open_button.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        open_button.setText("Open");
        open_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                open_buttonActionPerformed(evt);
            }
        });
        Save_button.add(open_button);

        save_button.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        save_button.setText("Save");
        save_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                save_buttonActionPerformed(evt);
            }
        });
        Save_button.add(save_button);

        Quit_button.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F4, java.awt.event.InputEvent.ALT_MASK));
        Quit_button.setText("Exit");
        Quit_button.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                Quit_buttonActionPerformed(evt);
            }
        });
        Save_button.add(Quit_button);

        Menu_bar.add(Save_button);

        Cipher_menu.setText("Cipher");

        DES_Menu.setText("DES");
        DES_Menu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DES_MenuActionPerformed(evt);
            }
        });
        Cipher_menu.add(DES_Menu);

        DES3_menu.setText("DESEDE");
        DES3_menu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                DES3_menuActionPerformed(evt);
            }
        });
        Cipher_menu.add(DES3_menu);

        AES_menu.setText("AES");
        AES_menu.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                AES_menuActionPerformed(evt);
            }
        });
        Cipher_menu.add(AES_menu);

        Menu_bar.add(Cipher_menu);

        setJMenuBar(Menu_bar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(base, javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(key)
                    .addComponent(IV)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(Key_label)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(Key_file)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(zero_key)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(key_key))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(IV_text)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(IV_file)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(zero_IV)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(key_IV))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addGap(171, 171, 171)
                        .addComponent(Cipher_label)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(Cipher_text, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGap(150, 150, 150))
                    .addComponent(result, javax.swing.GroupLayout.DEFAULT_SIZE, 579, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(Encrypt_button)
                                .addGap(18, 18, 18)
                                .addComponent(Decrypt_button)
                                .addGap(18, 18, 18)
                                .addComponent(XOR_button))
                            .addGroup(layout.createSequentialGroup()
                                .addComponent(Result_label)
                                .addGap(30, 30, 30)
                                .addComponent(spacing_text)
                                .addGap(18, 18, 18)
                                .addComponent(spacing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                        .addGap(0, 0, Short.MAX_VALUE))
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(Base_label)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(Base_file)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(zero_base)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(key_base)))
                .addContainerGap())
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 128, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 129, Short.MAX_VALUE)))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Cipher_label)
                    .addComponent(Cipher_text, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(10, 10, 10)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Base_label)
                    .addComponent(Base_file)
                    .addComponent(zero_base)
                    .addComponent(key_base))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(base, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Key_label)
                    .addComponent(zero_key)
                    .addComponent(key_key)
                    .addComponent(Key_file))
                .addGap(5, 5, 5)
                .addComponent(key, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(IV_text)
                    .addComponent(zero_IV)
                    .addComponent(key_IV)
                    .addComponent(IV_file))
                .addGap(5, 5, 5)
                .addComponent(IV, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Encrypt_button)
                    .addComponent(Decrypt_button)
                    .addComponent(XOR_button))
                .addGap(18, 18, 18)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(Result_label)
                    .addComponent(spacing_text)
                    .addComponent(spacing, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(result, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(0, 25, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGap(0, 25, Short.MAX_VALUE)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents
    private void button_pressed(Action action){
        
        //remove the spaces from the text fields
        key.setText(key.getText().replace(" ",""));
        base.setText(base.getText().replace(" ",""));
        IV.setText(IV.getText().replace(" ",""));
        
       try{     
           if(action == Action.XOR){
               
               //Pad with zeros until equal length
               while(base.getText().length() != key.getText().length()){
                   if(base.getText().length() < key.getText().length())
                       base.setText("0"+base.getText());
                   else
                       key.setText("0"+key.getText());
               }
               
               //Pad if not equal bytes
               if(base.getText().length() %2 != 0){
                   base.setText("0"+base.getText());
                   key.setText("0"+key.getText());
               }
               byte [] a = hexStringToByteArray(base.getText());
               byte [] b = hexStringToByteArray(key.getText());
               result.setText(bytesToHex(xorByteArray(a,b)));
               prevAction = Action.XOR;
               return;
           }
            //Figure out which type of encryption is being done
            Cipher myCipher;
            ETypes currentType;
            byte[] ivBytes;
            
            if(Cipher_text.getText().equals("")){
                currentType = ETypes.DES;
                Cipher_text.setText("DES");
            } 
            else
                currentType = ETypes.valueOf(Cipher_text.getText().toUpperCase());
            
            switch(currentType)
            {
                case AES: myCipher = Cipher.getInstance("AES/CBC/NoPadding"); 
                    //check key length
                    if(key.getText().length() % 16 != 0 ||
                            key.getText().length() < 32){
                        result.setText("*** Key must be either 16, 24, or 32 Bytes ***");
                        return;
                    }
                    
                    //check input length
                    if(base.getText().length() % 32 !=0 ){
                        result.setText("*** Base must be a multiple of 16 Bytes ***");
                        return;
                    }
                    
                    //check IV
                    if(IV.getText().length() != 32){
                        result.setText("*** IV must be 16 Bytes ***");
                        return;
                    }
                    
                    ivBytes = hexStringToByteArray(IV.getText());
   
                break;
                case DESEDE:    
                    myCipher = Cipher.getInstance("DESede/CBC/NoPadding");
                    
                    //check key length
                    if(key.getText().length() != 48){
                        result.setText("*** Key must be 24 Bytes ***");
                        return;
                    }
                    
                    //check input length
                    if(base.getText().length() % 16 !=0 ){
                        result.setText("*** Base must be a multiple of 8 Bytes ***");
                        return;
                    }
                    
                    //check IV
                    if(IV.getText().length() != 16){
                        result.setText("*** IV must be 8 Bytes ***");
                        return;
                    }
                   
                    ivBytes = hexStringToByteArray(IV_text.getText());
                    
                break;
                default:      
                    myCipher = Cipher.getInstance("DES/CBC/NoPadding");
                    
                    //check key length
                    if(key.getText().length() != 16){
                        result.setText("*** Key must be 8 Bytes ***");
                        return;
                    }
                    
                    //check input length
                    if(base.getText().length() % 16 !=0 ){
                        result.setText("*** Base must be a multiple of 8 Bytes ***");
                        return;
                    }
                    
                    if(IV.getText().length() != 16){
                        result.setText("*** IV must be 8 Bytes ***");
                        return;
                    }
              
                    ivBytes = hexStringToByteArray(IV.getText());           
                break;
            }
 
            //format the key
            SecretKeySpec myKey = new SecretKeySpec(hexStringToByteArray(key.getText()), Cipher_text.getText());
            IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
            
            byte[] base_bytes = hexStringToByteArray(base.getText());
            
            if(action == Action.ENCRYPT){
                //encrypt the input
                myCipher.init(Cipher.ENCRYPT_MODE, myKey, ivSpec);
                byte[] encrypted = new byte[myCipher.getOutputSize(base_bytes.length)];
                int enc_len = myCipher.update(base_bytes, 0 ,base_bytes.length, encrypted, 0 );
                enc_len += myCipher.doFinal(encrypted, enc_len);
                result.setText(bytesToHex(encrypted));   
                prevAction = Action.ENCRYPT;
                
                return;
            }
            
            //decrypt the input
            myCipher.init(Cipher.DECRYPT_MODE, myKey, ivSpec);
            byte[] decrypted = new byte[myCipher.getOutputSize(base_bytes.length)];
            int dec_len = myCipher.update(base_bytes, 0 ,base_bytes.length, decrypted, 0 );
            dec_len += myCipher.doFinal(decrypted, dec_len);
            result.setText(bytesToHex(decrypted));
            prevAction = Action.DECRYPT;
            return;
  
       }catch (Exception e) {
            System.err.println("Error:"+e.toString());
        }
    }

    private void Encrypt_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Encrypt_buttonActionPerformed
        Action action = Action.ENCRYPT;
        button_pressed(action);
        byteSpacing();
    }//GEN-LAST:event_Encrypt_buttonActionPerformed

    private void AES_menuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_AES_menuActionPerformed
        Cipher_text.setText("AES");
        IV.setText("00000000000000000000000000000000");
    }//GEN-LAST:event_AES_menuActionPerformed

    private void DES3_menuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DES3_menuActionPerformed
        Cipher_text.setText("DESEDE");
        IV.setText("0000000000000000");
    }//GEN-LAST:event_DES3_menuActionPerformed

    private void DES_MenuActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_DES_MenuActionPerformed
        Cipher_text.setText("DES");
        IV.setText("0000000000000000");
    }//GEN-LAST:event_DES_MenuActionPerformed

    private void Quit_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Quit_buttonActionPerformed
        System.exit(WIDTH);
    }//GEN-LAST:event_Quit_buttonActionPerformed

    private void Decrypt_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Decrypt_buttonActionPerformed
        Action action = Action.DECRYPT;
        button_pressed(action);
        byteSpacing();
    }//GEN-LAST:event_Decrypt_buttonActionPerformed

    private void XOR_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_XOR_buttonActionPerformed
        Action action = Action.XOR;
        button_pressed(action);
        byteSpacing();
    }//GEN-LAST:event_XOR_buttonActionPerformed

    private void Key_fileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Key_fileActionPerformed
        int returnVal = Open_fileChooser.showOpenDialog(this);
        if (returnVal == Open_fileChooser.APPROVE_OPTION) {
            File file = Open_fileChooser.getSelectedFile();
            try {
              // What to do with the file, e.g. display it in a TextArea
              key.read( new FileReader( file.getAbsolutePath() ), null );
            } catch (IOException ex) {
              System.out.println("problem accessing file"+file.getAbsolutePath());
            }
        }else{
            System.out.println("File access cancelled by user.");
        }
    }//GEN-LAST:event_Key_fileActionPerformed

    private void Base_fileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_Base_fileActionPerformed
        int returnVal = Open_fileChooser.showOpenDialog(this);
        if (returnVal == Open_fileChooser.APPROVE_OPTION) {
            File file = Open_fileChooser.getSelectedFile();
            try {
              // What to do with the file, e.g. display it in a TextArea
              base.read( new FileReader( file.getAbsolutePath() ), null );
            } catch (IOException ex) {
              System.out.println("problem accessing file"+file.getAbsolutePath());
            }
        }else{
            System.out.println("File access cancelled by user.");
        }
    }//GEN-LAST:event_Base_fileActionPerformed

    private void IV_fileActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_IV_fileActionPerformed
        int returnVal = Open_fileChooser.showOpenDialog(this);
        if (returnVal == Open_fileChooser.APPROVE_OPTION) {
            File file = Open_fileChooser.getSelectedFile();
            try {
              // What to do with the file, e.g. display it in a TextArea
              IV.read( new FileReader( file.getAbsolutePath() ), null );
            } catch (IOException ex) {
              System.out.println("problem accessing file"+file.getAbsolutePath());
            }
        }else{
            System.out.println("File access cancelled by user.");
        }
    }//GEN-LAST:event_IV_fileActionPerformed

    private void save_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_save_buttonActionPerformed
    int returnVal = Save_fileChooser.showSaveDialog(this);
    if (returnVal == Save_fileChooser.APPROVE_OPTION) {
        File file = Save_fileChooser.getSelectedFile();
        try {
          // What to do with the file, e.g. display it in a TextArea
          FileWriter fw = new FileWriter(file.getAbsoluteFile());
          fw.write("Base:"+base.getText());
          fw.write("\r\n");
          fw.write("Key:"+key.getText());
          fw.write("\r\n");
          fw.write("IV:"+IV.getText());
          fw.write("\r\n");
          fw.write("Action:"+prevAction.toString());
          fw.write("\r\n");
          fw.write("Result:"+result.getText());
          fw.write("\r\n");
          fw.close();

        } catch (IOException ex) {
          System.out.println("problem accessing file"+file.getAbsolutePath());
        }
    } else {
        System.out.println("File access cancelled by user.");
    }
    }//GEN-LAST:event_save_buttonActionPerformed
    private void byteSpacing(){
        if(result.getText() == null)
            return;
        
        
        int i = 1;
        int spacingInt = 0;
        if(spacing!= null)
            spacingInt = Integer.parseInt((String)spacing.getSelectedItem());
        
        result.setText(result.getText().replace(" ",""));
        
        if(spacingInt != 0){
            StringBuilder sb = new StringBuilder();
            for(char c: result.getText().toCharArray()){
                sb.append(c);
                if(i++%spacingInt == 0)
                    sb.append(" ");
            }
            result.setText(sb.toString());
        }
    }
    private void open_buttonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_open_buttonActionPerformed
    int returnVal = Open_fileChooser.showOpenDialog(this);
    if (returnVal == Open_fileChooser.APPROVE_OPTION) {
        File file = Open_fileChooser.getSelectedFile();
        BufferedReader br = null;
        try {
          // What to do with the file, e.g. display it in a TextArea
            String sCurrentLine;
            br = new BufferedReader(new FileReader(file.getAbsolutePath()));
 
            
                sCurrentLine = br.readLine();
                base.setText(sCurrentLine.substring(5,sCurrentLine.length()));
                sCurrentLine = br.readLine();
                key.setText(sCurrentLine.substring(4,sCurrentLine.length()));
                sCurrentLine = br.readLine();
                IV.setText(sCurrentLine.substring(3,sCurrentLine.length()));
                
        } catch (IOException ex) {
          System.out.println("problem accessing file"+file.getAbsolutePath());
        } finally{
            try{
                if(br != null)br.close();
            }catch (IOException ex){
                ex.printStackTrace();
            }
        }
    } else {
        System.out.println("File access cancelled by user.");
    }
    }//GEN-LAST:event_open_buttonActionPerformed

    private void zero_baseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zero_baseActionPerformed
        base.setText(base.getText()+"0000000000000000");
    }//GEN-LAST:event_zero_baseActionPerformed

    private void key_baseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_key_baseActionPerformed
        base.setText(base.getText()+"0123456789ABCDEF");
    }//GEN-LAST:event_key_baseActionPerformed

    private void zero_keyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zero_keyActionPerformed
        key.setText(key.getText()+"0000000000000000");
    }//GEN-LAST:event_zero_keyActionPerformed

    private void key_keyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_key_keyActionPerformed
        key.setText(key.getText()+"0123456789ABCDEF");
    }//GEN-LAST:event_key_keyActionPerformed

    private void zero_IVActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zero_IVActionPerformed
        IV.setText(IV.getText()+"0000000000000000");
    }//GEN-LAST:event_zero_IVActionPerformed

    private void key_IVActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_key_IVActionPerformed
        IV.setText(IV.getText()+"0123456789ABCDEF");
    }//GEN-LAST:event_key_IVActionPerformed

    private void baseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_baseActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_baseActionPerformed

    private void resultActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resultActionPerformed
    }//GEN-LAST:event_resultActionPerformed

    private void resultComponentAdded(java.awt.event.ContainerEvent evt) {//GEN-FIRST:event_resultComponentAdded
       byteSpacing();
    }//GEN-LAST:event_resultComponentAdded

    private void resultPropertyChange(java.beans.PropertyChangeEvent evt) {//GEN-FIRST:event_resultPropertyChange
        byteSpacing();        // TODO add your handling code here:
    }//GEN-LAST:event_resultPropertyChange

    private void spacingActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_spacingActionPerformed
        byteSpacing();
    }//GEN-LAST:event_spacingActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(EncryptionWindowMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(EncryptionWindowMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(EncryptionWindowMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(EncryptionWindowMain.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>
                
               
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                EncryptionWindowMain window = new EncryptionWindowMain();
                
                
                window.setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem AES_menu;
    private javax.swing.JButton Base_file;
    private javax.swing.JLabel Base_label;
    private javax.swing.JLabel Cipher_label;
    private javax.swing.JMenu Cipher_menu;
    private javax.swing.JLabel Cipher_text;
    private javax.swing.JMenuItem DES3_menu;
    private javax.swing.JMenuItem DES_Menu;
    private javax.swing.JButton Decrypt_button;
    private javax.swing.JButton Encrypt_button;
    private javax.swing.JTextField IV;
    private javax.swing.JButton IV_file;
    private javax.swing.JLabel IV_text;
    private javax.swing.JButton Key_file;
    private javax.swing.JLabel Key_label;
    private javax.swing.JMenuBar Menu_bar;
    private javax.swing.JFileChooser Open_fileChooser;
    private javax.swing.JMenuItem Quit_button;
    private javax.swing.JLabel Result_label;
    private javax.swing.JMenu Save_button;
    private javax.swing.JFileChooser Save_fileChooser;
    private javax.swing.JButton XOR_button;
    private javax.swing.JTextField base;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JTextField key;
    private javax.swing.JButton key_IV;
    private javax.swing.JButton key_base;
    private javax.swing.JButton key_key;
    private javax.swing.JMenuItem open_button;
    private javax.swing.JTextField result;
    private javax.swing.JMenuItem save_button;
    private javax.swing.JComboBox spacing;
    private javax.swing.JLabel spacing_text;
    private javax.swing.JButton zero_IV;
    private javax.swing.JButton zero_base;
    private javax.swing.JButton zero_key;
    // End of variables declaration//GEN-END:variables
}
